package cn.wolfcode.luowowo.search.service.impl;

import cn.wolfcode.luowowo.search.query.StrategySaechQuery;
import cn.wolfcode.luowowo.search.repository.StrategyRepository;

import cn.wolfcode.luowowo.search.service.IStrategySearchService;

import cn.wolfcode.luowowo.search.template.StrategyTemplate;

import cn.wolfcode.luowowo.search.vo.StatisVO;
import com.alibaba.dubbo.config.annotation.Service;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.aggregations.bucket.composite.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;

import java.util.*;

@Service
public class StrategySearchServiceImpl implements IStrategySearchService {
    @Autowired
    private StrategyRepository strategyRepository;
    @Autowired
    private ElasticsearchTemplate template;

    /**
     * 添加或编辑
     * @param template
     */
    @Override
    public void saveOrUpdate(StrategyTemplate template) {
        strategyRepository.save(template);
    }

    /**
     * 查询前十的主题
     * @return
     */
    @Override
    public List<Map<String, Object>> queryThemeTop10() {
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String,Object> map = null;
        List<StatisVO>vos = statisVOGroup("themeId","themeName","themeGroup",null);
        for (StatisVO vo : vos) {
            //获得目的地,因为目的地有很多字段,我们只用到了id和name,因此我们用map来封装就行
            List<StatisVO> dests = queryByThemeId(vo.getId());
            map = new HashMap<>();
            map.put("theme",vo);
            map.put("dests",dests);
            list.add(map);
        }
        //只需要前十个
        if (list.size()>10){
            list=list.subList(0,10);
        }
        return list;
    }
    //分组查询
    private List<StatisVO> statisVOGroup(String idField, String nameField, String groupName, BoolQueryBuilder query ) {
        List<CompositeValuesSourceBuilder<?>> sourceList = new ArrayList<>();
        TermsValuesSourceBuilder themeId = new TermsValuesSourceBuilder("id");
        TermsValuesSourceBuilder themeName = new TermsValuesSourceBuilder("name");
        themeId.field(idField);
        themeName.field(nameField);
        sourceList.add(themeId);
        sourceList.add(themeName);
        //第一个参数代表的是对应的自定义名字
        //第二个参数代表的是分组的list集合
        CompositeAggregationBuilder aggregationBuilder = new CompositeAggregationBuilder("themeGroup", sourceList);
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        //分组
        queryBuilder.addAggregation(aggregationBuilder);
        //分页
        queryBuilder.withPageable(PageRequest.of(0,1));
        //查询条件
        if (query!=null){
            queryBuilder.withQuery(query);
        }

        //得到查询结果之后还要把数据封住到map中
        AggregatedPage<StrategyTemplate> strategyTemplates = (AggregatedPage<StrategyTemplate>) strategyRepository.search(queryBuilder.build());
        InternalComposite group = strategyTemplates.getAggregations().get("themeGroup");
        Map<String,Object> map = null;
        StatisVO vo  = null;
        List<StatisVO>list = new ArrayList<>();
        for (CompositeAggregation.Bucket bucket : group.getBuckets()) {
            Long id = Long.parseLong(bucket.getKey().get("id").toString());
            String name = bucket.getKey().get("name").toString();
            Long count = bucket.getDocCount();
            vo  = new StatisVO(id,name,count);
            list.add(vo);
        }

        //排序
        Collections.sort(list, new Comparator<StatisVO>() {
            @Override
            public int compare(StatisVO o1,StatisVO o2) {
                Long ret = o2.getCount()-o1.getCount();
                return ret.intValue();
            }
        });
        return list;
    }


    /**
     *
     * @param themeId 主题id
     * @return
     */
    private  List<StatisVO> queryByThemeId(Long themeId){
        List<StrategyTemplate> dests = strategyRepository.findByThemeId(themeId);
        List<StatisVO> vos  =new ArrayList<>();
        //已添加的目的地名
        List<String>names = new ArrayList<>();
        for (StrategyTemplate dest : dests) {
            //判断是否存在目的地名
            if (!names.contains(dest.getDestName())) {
                StatisVO vo = new StatisVO();
                vo.setId(dest.getDestId());
                vo.setName(dest.getDestName());
                vos.add(vo);
                names.add(dest.getDestName());
            }
        }
        return vos;
    }
    @Override
    public List<StatisVO> queryConditionThemeGroup() {
        return  statisVOGroup("themeId","themeName", "themeGroup", null );
    }

    @Override
    public List<StatisVO> queryConditionProvincesGroup() {
        return statisVOGroup("provinceId","provinceName", "provinceGroup", null );
    }

    @Override
    public List<StatisVO> queryConditionAbroadsGroup() {
        BoolQueryBuilder query = QueryBuilders.boolQuery()
                .mustNot(QueryBuilders.termQuery("countryId", 1));
        return  statisVOGroup("countryId","countryName", "countryGroup",query);
    }

    @Override
    public Page query(StrategySaechQuery qo) {
        Pageable pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(),
                Sort.Direction.DESC, qo.getOrderBy());
        TermQueryBuilder builder = null;
        if (qo.getType()==StrategySaechQuery.CONDITION_TYPE_ABROAD){
            builder = QueryBuilders.termQuery("countryId",qo.getTypeValue());
        }else if (qo.getType()==StrategySaechQuery.CONDITION_TYPE_CHINA){
            builder=QueryBuilders.termQuery("provinceId",qo.getTypeValue());
        }else if (qo.getType()==StrategySaechQuery.CONDITION_TYPE_THEME){
            builder=QueryBuilders.termQuery("themeId",qo.getTypeValue());
        }
        if (builder!=null){
            return strategyRepository.search(builder,pageable);
        }

        return strategyRepository.findAll(pageable);
    }

    @Override
    public List<StrategyTemplate> findByName(String name) {
        return strategyRepository.findByDestName(name);
    }
}
